using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;

namespace BlancoWorld.EventReceiversManager 
{
    public class AddEventReceiverPage : LayoutsPageBase
    {
        protected SPWeb _spWeb = null;
        protected SPList _spList = null;
        protected Guid _spListId = Guid.Empty;
        protected Label lblWarning;
        protected DropDownList ddlEventType;
        protected TextBox txtAssembly;
        protected TextBox txtClassName;

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            SiteMap.Providers["SPXmlContentMapProvider"].SiteMapResolve += new SiteMapResolveEventHandler(provider_SiteMapResolve);

            try
            {
                _spWeb = SPControl.GetContextWeb(Context);
                _spListId = new Guid(Server.UrlDecode(Request.QueryString["ListId"].ToString()));
                _spList = _spWeb.Lists[_spListId];
            }
            catch (Exception)
            {
                throw new Exception(String.Format("Unable to locate list {0}.", _spListId.ToString()));
            }

            BindEventTypes();
        }

        protected void BindEventTypes()
        {
            string[] eventTypes = new string[] {String.Empty, "Context Event", "Email Received", "Field Added", "Field Adding", 
                "Field Deleted", "Field Deleting", "Field Updated", "Field Updating", "Item Added", "Item Adding", 
                "Item Attachment Added", "Item Attachment Adding", "Item Attachment Deleted", "Item Attachment Deleting", 
                "Item Checked In", "Item Checked Out", "Item Checking In", "Item Checking Out", "Item Deleted", "Item Deleting", 
                "Item File Converted", "Item File Moved", "Item File Moving", "Item Unchecked Out", "Item Unchecking Out", 
                "Item Updated", "Item Updating" };
            ddlEventType.DataSource = eventTypes;
            ddlEventType.DataBind();
        }

        protected override void OnLoad(EventArgs e)
        {
                
        }

        protected override void OnUnload(EventArgs e)
        {
            base.OnUnload(e);

            //detach from the static SiteMapResolve event and restore localization mode              
            SiteMap.Providers["SPXmlContentMapProvider"].EnableLocalization = true;
            SiteMap.Providers["SPXmlContentMapProvider"].SiteMapResolve -= new SiteMapResolveEventHandler(provider_SiteMapResolve);
        }

        protected virtual bool IsSamePage(HttpContext context1, HttpContext context2)
        {
            //by default, the contexts are considered the same if they            
            //map to the same file and the same listid/itemid       
            return ((Server.MapPath(context1.Request.AppRelativeCurrentExecutionFilePath) ==
                Server.MapPath(context2.Request.AppRelativeCurrentExecutionFilePath)) &&
                (context1.Request.QueryString == context2.Request.QueryString));
        }

        protected void RedirectToSource()
        {
            string sourceUrl = Request.QueryString["SourceUrl"].ToString();
            Response.Redirect(sourceUrl);
        }

        protected SPEventReceiverType EventReceiverType(string eventTypeString)
        {
            SPEventReceiverType evType = SPEventReceiverType.InvalidReceiver;

            switch (eventTypeString)
            {
                case "Context Event":
                    evType = SPEventReceiverType.ContextEvent;
                    break;

                case "Email Received":
                    evType = SPEventReceiverType.EmailReceived;
                    break;

                case "Field Added":
                    evType = SPEventReceiverType.FieldAdded;
                    break;

                case "Field Adding":
                    evType = SPEventReceiverType.FieldAdding;
                    break;

                case "Field Deleted":
                    evType = SPEventReceiverType.FieldDeleted;
                    break;

                case "Field Deleting":
                    evType = SPEventReceiverType.FieldDeleting;
                    break;

                case "Field Updated":
                    evType = SPEventReceiverType.FieldUpdated;
                    break;

                case "Field Updating":
                    evType = SPEventReceiverType.FieldUpdating;
                    break;

                case "Item Added":
                    evType = SPEventReceiverType.ItemAdded;
                    break;

                case "Item Adding":
                    evType = SPEventReceiverType.ItemAdding;
                    break;

                case "Item Attachment Added":
                    evType = SPEventReceiverType.ItemAttachmentAdded;
                    break;

                case "Item Attachment Adding":
                    evType = SPEventReceiverType.ItemAttachmentAdding;
                    break;

                case "Item Attachment Deleted":
                    evType = SPEventReceiverType.ItemAttachmentDeleted;
                    break;

                case "Item Attachment Deleting":
                    evType = SPEventReceiverType.ItemAttachmentDeleting;
                    break;

                case "Item Checked In":
                    evType = SPEventReceiverType.ItemCheckedIn;
                    break;

                case "Item Checked Out":
                    evType = SPEventReceiverType.ItemCheckedOut;
                    break;

                case "Item Checking In":
                    evType = SPEventReceiverType.ItemCheckingIn;
                    break;

                case "Item Checking Out":
                    evType = SPEventReceiverType.ItemCheckingOut;
                    break;

                case "Item Deleted":
                    evType = SPEventReceiverType.ItemDeleted;
                    break;

                case "Item Deleting":
                    evType = SPEventReceiverType.ItemDeleting;
                    break;

                case "Item File Converted":
                    evType = SPEventReceiverType.ItemFileConverted;
                    break;

                case "Item File Moved":
                    evType = SPEventReceiverType.ItemFileMoved;
                    break;

                case "Item File Moving":
                    evType = SPEventReceiverType.ItemFileMoving;
                    break;

                case "Item Unchecked Out":
                    evType = SPEventReceiverType.ItemUncheckedOut;
                    break;

                case "Item Unchecking Out":
                    evType = SPEventReceiverType.ItemUncheckingOut;
                    break;

                case "Item Updated":
                    evType = SPEventReceiverType.ItemUpdated;
                    break;

                case "Item Updating":
                    evType = SPEventReceiverType.ItemUpdating;
                    break;

                default:
                    evType = SPEventReceiverType.InvalidReceiver;
                    break;
            }

            return evType;
        }

        protected void btnOK_Click(object sender, EventArgs e)
        {
            try
            {
                if (ddlEventType.SelectedItem.Value == String.Empty || txtAssembly.Text.Trim().Length == 0 ||
                    txtClassName.Text.Trim().Length == 0)
                {
                    lblWarning.Text = "Please complete all of the fields above.";
                }
                else
                {
                    SPEventReceiverType evType = EventReceiverType(ddlEventType.SelectedItem.Value);
                    if (evType == SPEventReceiverType.InvalidReceiver)
                    {
                        lblWarning.Text = "Invalid event type - please select a valid event type.";
                    }
                    else
                    {
                        _spList.EventReceivers.Add(evType, txtAssembly.Text.Trim(), txtClassName.Text.Trim());
                        RedirectToSource();
                    }
                }
            }
            catch (Exception ex)
            {
                lblWarning.Text = String.Format("Error while trying to add event receiver: {0}", ex.Message);
            }
        }

        protected void btnCancel_Click(object sender, EventArgs e)
        {
            RedirectToSource();
        }

        protected SiteMapNode provider_SiteMapResolve(object sender, SiteMapResolveEventArgs e)
        {
            if (!IsSamePage(Context, e.Context))
            {
                e.Provider.EnableLocalization = true;
                return e.Provider.CurrentNode;
            }

            SiteMapNode pageTitleNode;
            SiteMapNode eventReceiversNode;
            SiteMapNode settingsNode;
            SiteMapNode listNode;
            try
            {
                // Trun off localization, so that the custom nodes do not get overwritten                 
                e.Provider.EnableLocalization = false;

                // Clone some node to get a valid node object and modify it.                 
                listNode = e.Provider.RootNode.ChildNodes[0].Clone();
                listNode.Url = _spList.DefaultViewUrl;
                listNode.Title = _spList.Title;
                listNode.ChildNodes = new SiteMapNodeCollection();

                // Add the settings node
                settingsNode = new SiteMapNode(e.Provider, Guid.NewGuid().ToString());
                settingsNode.Url = String.Format("{0}/_layouts/listedit.aspx?List={1}",
                    _spWeb.Url, Server.UrlEncode(_spList.ID.ToString()));
                settingsNode.Title = "Settings";
                settingsNode.ChildNodes = new SiteMapNodeCollection();
                listNode.ChildNodes.Add(settingsNode);
                settingsNode.ParentNode = listNode;

                // Add the event receivers node
                eventReceiversNode = new SiteMapNode(e.Provider, Guid.NewGuid().ToString());
                eventReceiversNode.Url = String.Format("{0}/_layouts/BlancoWorld.EventReceiversManager/EventReceiversManager.aspx?List={1}",
                    _spWeb.Url, Server.UrlEncode(_spList.ID.ToString()));
                eventReceiversNode.Title = "Event Receivers";
                eventReceiversNode.ChildNodes = new SiteMapNodeCollection();
                settingsNode.ChildNodes.Add(eventReceiversNode);
                eventReceiversNode.ParentNode = settingsNode;

                // Add the actual page node
                pageTitleNode = new SiteMapNode(e.Provider, Guid.NewGuid().ToString());
                pageTitleNode.Title = "Add Event Receiver";
                eventReceiversNode.ChildNodes.Add(pageTitleNode);
                pageTitleNode.ParentNode = eventReceiversNode;
            }
            catch (Exception)
            {
                return e.Provider.CurrentNode;
            }
            return pageTitleNode;
        }

    }
}
